#include "cardutil.h"

CardUtil::CardUtil(QObject *parent) : QThread(parent)
{

}

bool CardUtil::loadList(uint num)
{
    uint tempNum = 0;
    do{
        QThread::usleep(1);
        tempNum = load_list(num, 0U);
    }while(tempNum != num && mMarking);
    return mMarking;
}

int CardUtil::setMarkerParamsList()
{
    int listLevel = 0;
    LaserParam& laserParam = mMarkerParam.laserParams();

    if(laserParam.laserMode() == 0){
        set_standby_list(laserParam.halfPeriod(),
                         laserParam.pulseLength());
    }else{
        set_standby_list(0, 0);
    }

    set_laser_pulses(laserParam.halfPeriod(),
                     laserParam.pulseLength());
    qDebug() << "set_laser_pulses=>" << QString::number(laserParam.halfPeriod())
             << QString::number(laserParam.pulseLength());

    write_da_1_list(laserParam.power() * 4095 / 100);


    set_laser_delays(laserParam.laserOnDelay(),
                     laserParam.laserOffDelay());

    qDebug() << "set_laser_delays       =>"
             << QString::number(laserParam.laserOnDelay())
             << QString::number(laserParam.laserOffDelay());
    set_scanner_delays(laserParam.jumpDelay(),
                       laserParam.markDelay(),
                       laserParam.polygonDelay());

    qDebug() << "set_scanner_delays       =>"
             << QString::number(laserParam.jumpDelay())
             << QString::number(laserParam.markDelay())
             << QString::number(laserParam.polygonDelay());
    set_jump_speed(laserParam.jumpSpeed()); //跳转速度

    qDebug() << "set_jump_speed       =>"
             << QString::number(laserParam.jumpSpeed());
    set_mark_speed(laserParam.markSpeed());  //标刻速度

    qDebug() << "set_mark_speed       =>"
             << QString::number(laserParam.markSpeed());
    return listLevel;
}

int firstPos = 0;

bool CardUtil::mark(QList<MarkerPath> pathList)
{
    //第一次需要手动执行列表
    bool isFirst = true;
    //当前列表的序号,默认从列表1开始,然后1和2相互切换
    uint tempNum = 1U;
    //当前列表命令写入到第几个,当达到整个列表的数量的时候需要切换列表
    uint listLevel = 0U;
    //列表是否满了
    bool isFull = false;

    //加载第一个列表
    if(!loadList(tempNum)){
        return false;
    }


    //加载每一个图形打印参数
    setMarkerParamsList();
    //缓存时间
//    save_and_restart_timer();
//

    //是否飞动校正
    if(mMarkerParam.fly2DParam().isCorrable()){
//        store_encoder(0U);
//        qDebug() << "store_encoder" << 0;
//

        get_list_pointer(tempNum, listLevel);
        firstPos = listLevel;
    }


    for(int m = 0; m < pathList.size(); m++){
        qDebug() << "shape start==========================" << m;

        if(mMarkerParam.fly2DParam().isEnable()){
            if(externalStart){
                //达到计数后,立刻使用set_fly_x重置计数器,此时计数器为0
                double flyx = mMarkerParam.fly2DParam().scaleX();
                list_nop();
                set_fly_x(flyx);

            }else{
//                //保证wait_for_encoder期间不会出光
//                list_nop();
//
//                //根据上一次打印的图形宽度来计算本次需要等待的计数值
//                int flyWaitCount = lastPath * k_value
//                        / mMarkerParam.fly2DParam().scaleX();
//                //等待计数器达到flyWaitCount的值
//                wait_for_encoder(flyWaitCount, 0);
//                qDebug() << "wait_for_encoder" << flyWaitCount << "0";
//
//                //达到计数后,立刻使用set_fly_x重置计数器,此时计数器为0
//                double flyx = mMarkerParam.fly2DParam().scaleX();
//                set_fly_x(flyx);
//
//                qDebug() << "set_fly_x"  << flyx;
            }
        }

        MarkerPath path = pathList.at(m);
        for(int i = 0; i < path.size(); i++){
            MarkerElement element = path.at(i);
            qDebug() << "pos=" << element.x() << element.y();
            qDebug() << "k=" << k_value;
            element *= k_value;
            if(element.type() == JumpTo){
                jump_abs(element.x(), element.y());

            }else if(element.type() == MarkTo){
                mark_abs(element.x(), element.y());

            }else if(element.type() == Arc_To){
                arc_abs(element.x(), element.y(), element.angle());

            }else if(element.type() == JumpLaserOn){
                laser_on_list(element.time() * 100);
                qDebug() << "laser_on_list=>" << element.time() * 100;

            }
            if(!mMarking){//停止标刻,则直接跳出,不再执行
                set_standby_list(0, 0);
                jump_abs(0, 0);
                set_extstartpos_list(0);
                set_end_of_list();
                qDebug() << "set_end_of_list";
                return false;
            }

//            get_list_pointer(tempNum, listLevel);
//            if(listLevel < 4000U - 300U){ //预留300个位置,以防超出列表范围
//                //列表没有写满,继续在同一个列表写入命令
//                continue;
//            }
//            //列表写满
//            set_end_of_list();
//            qDebug() << "set_end_of_list=>";
//            auto_change(); //自动切换列表
//            qDebug() << "auto_change=>";
//            isFull = true;
//            if(isFirst != externalStart){//如果是第一次循环,需要手动调用列表执行
//                isFirst = false;
//                execute_list(tempNum);
//                qDebug() << "execute_list=>" << tempNum;
//            }
//            tempNum = (tempNum == 1U ? 2U : 1U);//切换列表序号
//            listLevel = 0;//重置命令数量

//            if(!loadList(tempNum)){//标记列表已满,如果还有命令去另一个列表写
//                return false;
//            }
        }
        if(externalStart){
            fly_return(0, 0);
            if(m == pathList.size() - 1){
                set_extstartpos_list(firstPos);
                qDebug() << "set_extstartpos_list" << firstPos;
            }else{
                get_list_pointer(tempNum, listLevel);
                set_extstartpos_list(listLevel + 2);
                qDebug() << "set_extstartpos_list" << (listLevel + 2);
            }
            set_end_of_list();
            qDebug() << "set_end_of_list";
        }else{
            //记录本次打印的图形宽度
//            lastPath = path.width();
        }
        qDebug() << "shape end==========================" << m;
    }

//    if(externalStart){
//        //结束之后获取计数,飞动校正使用
//        if(mMarkerParam.fly2DParam().isCorrable()){
//            store_encoder(1U);
//            qDebug() << "store_encoder" << 1;
//        }
//        //结束之后归位
//        if(mMarkerParam.fly2DParam().isEnable()){
//            fly_return(0, 0);
//            qDebug() << "fly_return" << "0, 0";
//        }
//        set_end_of_list();
//    }else{
//        set_standby_list(0, 0);
//        jump_abs(0, 0);
//        //缓存时间
//        save_and_restart_timer();
//        list_nop();
//        set_end_of_list();
//        qDebug() << "set_end_of_list=>";
//        auto_change(); //自动切换列表
//        qDebug() << "auto_change=>";
//        if(isFirst){
//            isFirst = false;
//            execute_list(tempNum);
//            qDebug() << "execute_list(out loop)=>" << tempNum;
//        }
//        //检查图形已经标刻完毕,两个列表都处于空闲状态
//        if(!loadList(2)){
//            return false;
//        }
//        if(!loadList(1)){
//            return false;
//        }
//        //结束之后获取计数,飞动校正使用
//        if(mMarkerParam.fly2DParam().isCorrable()){
//            store_encoder(1U);
//            qDebug() << "store_encoder" << 1;
//        }
//        //结束之后归位
//        if(mMarkerParam.fly2DParam().isEnable()){
//            fly_return(0, 0);
//            qDebug() << "fly_return" << "0, 0";
//        }
//        set_end_of_list();
//        qDebug() << "set_end_of_list=>";
//        execute_list(1);
//    }
    return true;
}

void CardUtil::run()
{
    mRuning = true;
    mMarking = true;
    while(mRuning){
        if(mQueue.isEmpty()){
            QThread::msleep(1);
            continue;
        }
        MarkerJob job = mQueue.dequeue();
        mMarkerParam = job.markerParam().toRTCMarkParams(k_value);
        set_laser_mode(mMarkerParam.laserParams().laserMode());
        set_laser_control(0);

        emit sig_markStarted(job.id());

        bool ret = mark(job.pathList());
        if(!ret){
            stopMark();
        }
        int time = get_mark_time();
        emit sig_markFinished(job.id(), get_last_error(), time);
        QThread::msleep(1);
    }
}

void CardUtil::addJob(MarkerJob job)
{
    mQueue.append(job);
}

void CardUtil::setKValue(uint k)
{
    k_value = k;
}

void CardUtil::stopMark()
{
    stop_execution();
    mQueue.clear();
    mMarking = false;
}

int CardUtil::get_mark_time()
{
    double time = get_time() * 1000;
    return qRound(time);
}

void CardUtil::readEncoder(long& enc00, long& enc10, long& enc01, long& enc11)
{
    read_encoder(enc00, enc10, enc01, enc11);
}

void CardUtil::getEncoder(long& enc1, long& enc2)
{
    get_encoder(enc1, enc2);
}

void CardUtil::setControlMode(uint m)
{
    set_control_mode(m);
    externalStart = (m == 1U);
}
